#ifndef __ENVIRONMENT_H_
#define __ENVIRONMENT_H_

#include <list>
#include <string>

class RobotBase;
class ObstacleBase;
class PlanningCommand;
class ModelInstance;

struct UncompressedRobotInfo
{
	bool used;
	int full_dim_state;
	int full_joint_num;
	short* full_joint_param_id; // old joint num, old param id
	short* full_joint_compressed_param_id; // old joint num, new param id
	float* full_init_confs;
	float* full_goal_confs;

	UncompressedRobotInfo()
	{
		used = false;
		full_dim_state = 0;
		full_joint_num = 0;
		full_joint_param_id = NULL;
		full_joint_compressed_param_id = NULL;
		full_init_confs = NULL;
		full_goal_confs = NULL;
	}

	~UncompressedRobotInfo()
	{
		delete [] full_joint_param_id;
		delete [] full_joint_compressed_param_id;
		delete [] full_init_confs;
		delete [] full_goal_confs;
	}
};

class EnvironmentBase
{
public:
	EnvironmentBase(std::string const& cmd_file_name);
	
	~EnvironmentBase();
	
	void set_robot(RobotBase* robot);
	
	RobotBase* get_robot() const;
	
	void add_obstacle(ObstacleBase* obstacle);
	
	ObstacleBase* get_obstacle(int i) const;
	
	int obstacle_size() const;
	
	void print() const;
	
	void add_model(ModelInstance* model);
	
	void setup_GL_instance();
	
	void merge_obstacles();

	void post_process();
	
	RobotBase* m_robot;
	
	ObstacleBase** m_obstacles;
	int m_num_obstacles;
	ModelInstance** m_models;
	int m_num_models;
	
	
	std::list<ObstacleBase*> m_obstacles_;
	
	// list of models/objects in the scene, contains geometry
	// information
	std::list<ModelInstance*> m_models_;
	
	PlanningCommand* m_cmd;

	UncompressedRobotInfo m_uncompressed_info;

};


#endif